/** Name: Parse.java
 *  
 *  @author: Sunny Toor
 *  
 *  Description: This 
 *  
 *  Last modified: 9th September 2011
 * 
 */
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Hashtable;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.*;

/**
 * <b>Description:</b><br/> It reads in an XSD description of a schema and constructs an internal
 * 		representation of the XSD file and stores it in a hashtable. This [hashtable] datastructure
 * 		is used by other classes. This class only populates the <i>key</i> and the value is left
 * 		for other classes to be filled according to the user-input provided.   
 * 
 * <br/><br/><b>Last modified:</b><br/> 16th August 2011
 * 
 * @author Sunny Toor
 * @param N/A
 * @return N/A
 * @exception N/A
 * 
 */
public class ParseSchema implements java.io.Serializable{

	/** version UID */
	private static final long serialVersionUID = 1L;
	/** datastructure to store the mapping */
	private Hashtable<String, String> elementMap;
	
	
	/**
	 * <b>Description:</b><br/> This method returns a tree representation of all the nested 
	 * 		elements from a valid XSD file name. 
	 * 
	 * <br/><br/><b>Last modified:</b><br/> 16th August 2011
	 * 
	 * @author Sunny Toor
	 * @param XSD file name
	 * @return a tree representation of the XSD document
	 * @exception File IO Exception
	 * 
	 */
	public Document getDocReprensation(String fileName)throws Exception {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(new File(fileName));
		
		return doc;
	}
	
	/**
	 * <b>Description:</b><br/> This is the method that goes through tree representation of the entire XSD document
	 * 		and extracts all the information from it. It then stores this extracted information in the hashtable.
	 * 		
	 * 
	 * <br/><br/><b>Last modified:</b><br/> 16th August 2011
	 * 
	 * @author Sunny Toor
	 * @param Node of the tree representation of the XSD document
	 * @return N/A
	 * @exception File IO Exception
	 * 
	 */
	public void traverseDoc(Node node, PrintStream out) throws Exception{
		if (node == null){
			return;
		}
		int type = node.getNodeType();
		if(type==Node.ELEMENT_NODE){
			if(node.toString().matches(".*xsd:element.*")){
				//node.getAttributes().getNamedItem("name");
				int elementLength = node.getAttributes().getLength();
				for(int i=0; i<elementLength; i++){
					String ele = node.getAttributes().item(i).toString();
					//out.print(ele);
					//out.print("  ");
					if(ele.matches("name.*")){
						String strippedEle = ele.replaceAll(".*name=\"(.*)\"", "$1");
						this.elementMap.put(strippedEle, "NA");
						if(out != null){
							out.println(strippedEle);
						}
					}		
				}
				//out.println();
			}
		}
		NodeList childNodes = node.getChildNodes();
		if(childNodes != null){
			int numOfChilds = childNodes.getLength();
			for(int i=0; i<numOfChilds; i++){
				traverseDoc(childNodes.item(i),out);
			}
		}
		
	}
	
	/**
	 * <b>Description:</b><br/> Returns the hashtable
	 * 
	 * <br/><br/><b>Last modified:</b><br/> 14th August 2011
	 * 
	 * @author Sunny Toor
	 * @param N/A
	 * @return Hashtable
	 * @exception N/A
	 * 
	 */
	public Hashtable<String,String> getElementMap(){
		return this.elementMap;
	}
	
	/**
	 * <b>Description:</b><br/> Constructor that initialises the hashtable data-structure.
	 * 
	 * <br/><br/><b>Last modified:</b><br/> 14th August 2011
	 * 
	 * @author Sunny Toor
	 * @param n/a
	 * @return n/a
	 * @exception n/a
	 * 
	 */
	public ParseSchema() {
		// TODO Auto-generated constructor stub
		elementMap = new Hashtable<String, String>();
	}

	/**
	 * <b>Description:</b><br/> Main method which drives the entire class
	 * 
	 * <br/><br/><b>Last modified:</b><br/> 14th August 2011
	 *  
	 * @author Sunny Toor 
	 * @param args
	 * @return n/a
	 * @exception File IO Exception
	 * 
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		ParseSchema p = new ParseSchema();
		Document d = p.getDocReprensation("mods-schema.xml");
		p.traverseDoc(d, System.out);

	}

}
